/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.brain.conf.manager;

import com.brain.conf.dto.MonedaDto;
import com.brain.conf.dto.ProductoDetaDto;
import com.brain.conf.dto.ProductoDto;
import com.brain.conf.dto.UnidadMedidaDto;
import com.brain.conf.view.util.ConstantesConf;
import com.brain.core.common.UtilCore;
import com.brain.core.manager.*;
import com.brain.core.configuracion.WebServletContextListener;
import com.brain.core.exception.DAOException;
import com.brain.core.hibernate.dao.DAOGenerico;
import com.brain.core.view.mbean.ApplicationMBean;
import com.brain.core.view.mbean.SessionMBean;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

/**
 * @author Greip Company
 * @since 22/01/2014
 * @version 1.0
 */
@Service
public class ProductoDetaManager extends ComunManager<ProductoDetaDto> implements Serializable {

    /**
     * Guarda las acciones del sistema en un archivo de texto plano
     *
     * @since 09/01/2014
     */
    private static Logger logger = Logger.getLogger(ProductoDetaManager.class);
    /**
     * Objeto tipo Long de la entidad ProductoDetaDto
     *
     * @since 22/01/2014
     */
    private Long idEntidad = 255L;
    /**
     * Objeto que permite el acceso a la capa de datos
     *
     * @since 09/01/2014
     */
    @Resource
    private DAOGenerico<ProductoDetaDto> springHibernateDao;
    /**
     * Objeto que permite el acceso a la capa de datos de la clase
     * RecursosManager
     *
     * @since 09/01/2014
     */
    @Resource
    private RecursosManager recursosManager;
    /**
     * Objeto que permite el acceso a la capa de datos de la clase
     * ParametroManager
     *
     * @since 09/01/2014
     */
    @Resource
    private ParametroManager parametroManager;
    /**
     * Objeto que permite el acceso a la capa de datos de la clase
     * AlmacenUbicacionManager
     *
     * @since 09/01/2014
     */
    @Resource
    private AlmacenUbicacionManager auManager;
    /**
     * Objeto que permite el acceso a la capa de datos de la clase
     * ProductoManager
     *
     * @since 09/01/2014
     */
    @Resource
    private ProductoManager productoManager;

    /**
     * Metodo que devuelve un Dto
     *
     * @since 22/01/2014
     * @param id identificador o codigo en la tabla a obtener
     * @return retorna un Dto lleno de datos en caso que encuentre coincidencias
     * con el parámetro enviado
     */
    public ProductoDetaDto obtenerPorId(Long id) throws DAOException {
        return springHibernateDao.obtenerDtoPorId(ProductoDetaDto.class, id);
    }

    /**
     * Metodo que obtiene todos los datos de la entidad coincidentes con el
     * filtro
     *
     * @since 22/01/2014
     * @param dtoFiltro es el objeto de la clase ProductoDto , que contiene los
     * valores para filtrar el query
     * @return retorna una lista con todos los datos de la entidad coincidentes
     * con el filtro
     */
    public List<ProductoDetaDto> obtener(ProductoDto dtoFiltro) throws DAOException {
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        String hqsql = "select e from ProductoDetaDto as e where e.id=e.id ";
        List<Object> listaParametros = new ArrayList<Object>();

        if (dtoFiltro.getId() != null && !dtoFiltro.getId().equals(0L)) {
            hqsql += " and e.id = ?";
            listaParametros.add(dtoFiltro.getId());
        }

        if (dtoFiltro.getDescripcion() != null && dtoFiltro.getDescripcion().length() != 0) {
            hqsql += " and upper(e.productoDto.descripcion) like '%" + dtoFiltro.getDescripcion().toUpperCase() + "%'";
        }

        if (dtoFiltro.getSku() != null && dtoFiltro.getSku().length() != 0) {
            hqsql += " and upper(e.sku) like '%" + dtoFiltro.getSku().toUpperCase() + "%'";
        }

        if (dtoFiltro.getTipoProducto() != null && dtoFiltro.getTipoProducto().length() != 0 && !dtoFiltro.getTipoProducto().equals(ConstantesConf.ValoresConstantes.PRODUCTO_COD_TIPO_TODOS)) {
            hqsql += " and upper(e.productoDto.tipoProducto) = '" + dtoFiltro.getTipoProducto().toUpperCase() + "'";
        }

        if (dtoFiltro.getGrupoDto().getId() != null && !dtoFiltro.getGrupoDto().getId().equals(0L) && !dtoFiltro.getGrupoDto().getId().equals(parametroManager.getIdTodos())) {
            hqsql += " and e.productoDto.grupoDto.id = ?";
            listaParametros.add(dtoFiltro.getGrupoDto().getId());
        }

        if (dtoFiltro.getFamiliaDto().getId() != null && !dtoFiltro.getFamiliaDto().getId().equals(0L) && !dtoFiltro.getFamiliaDto().getId().equals(parametroManager.getIdTodos())) {
            hqsql += " and e.productoDto.familiaDto.id = ?";
            listaParametros.add(dtoFiltro.getFamiliaDto().getId());
        }

        if (dtoFiltro.getStockActual() != null && !dtoFiltro.getStockActual().equals(0L)) {
            hqsql += " and e.stockActual = ? )";
            listaParametros.add(dtoFiltro.getStockActual());
        }

        if (dtoFiltro.getEstado() != null) {
            hqsql += " and e.productoDto.estado = ?";
            listaParametros.add(dtoFiltro.getEstado());
        }

        hqsql += " and e.productoDto.empresaDto.id = ? ";
        listaParametros.add(sessionMBean.getEmpresaDto().getId());

        //Agregamos la condicion que valida propietarios
        if (!sessionMBean.getSessionUsuarioDto().getRolDto().getId().equals(sessionMBean.getRolSystem())) {
            if (sessionMBean.getOrganizacionDto() != null && sessionMBean.getOrganizacionDto().getId() != null) {
                if (!sessionMBean.getSessionUsuarioDto().getRolDto().getUsuarioDefault()) {
                    hqsql += " and exists(select 'X' from PropietarioDto as prop ";
                    hqsql += " where prop.pk.organizacionDto.id = ? ";
                    hqsql += " and prop.pk.entidad = ? ";
                    hqsql += " and prop.pk.registro = e.productoDto.id)";
                    listaParametros.add(sessionMBean.getOrganizacionDto().getId());
                    listaParametros.add(productoManager.getIdEntidad());
                }
            }
        }

        hqsql += " order by e.productoDto.descripcion asc, e.productoDto.fecha desc";
        return springHibernateDao.ejecutarQuery(hqsql, listaParametros);
    }

    /**
     * Metodo que instancia e inicializa los valores de la clase ProductoDetaDto
     * @param  prodDto objeto de la clase ProductoDto
     * @since 22/01/2014
     * @return retorna el dto inicializado
     */
    public ProductoDetaDto inicializar(ProductoDto prodDto) {
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        ProductoDetaDto dto = new ProductoDetaDto();
        dto.setProductoDto(prodDto);
        
        dto.setUnidadMedidaDto(new UnidadMedidaDto(ConstantesConf.Entidad.UNI_MED_UNIDAD));
        
        dto.setEstado(Boolean.TRUE);
        dto.setAutogenerarSku(Boolean.FALSE);
        dto.setMonedaCompraDto(sessionMBean.getEmpresaDto().getMonedaDto());
        dto.setMonedaVentaDto(sessionMBean.getEmpresaDto().getMonedaDto());
        dto.setDescuentoCompra(BigDecimal.ZERO);
        dto.setDescuentoVenta(BigDecimal.ZERO);
        dto.setPrecioCompra(BigDecimal.ZERO);
        dto.setPrecioVenta(BigDecimal.ZERO);
        dto.setStockActual(BigDecimal.ZERO);
        dto.setStockMinimo(BigDecimal.ZERO);
        dto.setStockMaximo(BigDecimal.ZERO);
        dto.setVentaSinStock(Boolean.TRUE);
        
        if (sessionMBean.getOrganizacionDto() != null) {
            if (sessionMBean.getOrganizacionDto().getId() != null) {
                //Obtenemos la moneda del pais de la organizacion   
                dto.setMonedaCompraDto(sessionMBean.getOrganizacionDto().getMonedaDto());
                dto.setMonedaVentaDto(sessionMBean.getOrganizacionDto().getMonedaDto());
            }
        }
        return dto;
    }

    /**
     * Metodo que permite gestionar las acciones DML del objeto dto de la clase
     * ProductoDetaDto
     *
     * @param dto objeto de la clase ProductoDetaDto
     * @since 22/01/2014
     * @return retorna la url de la pagina de financiamientoLetra o ún valor
     * nulo en caso pase un error
     */
    public String guardar(ProductoDetaDto dto, int accion) {

        String to = null;
        String mensajeTrx = "";
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        ApplicationMBean applicationMBean = (ApplicationMBean) WebServletContextListener.getApplicationContext().getBean("applicationMBean");

        {
            dto.setUsuarioDto(sessionMBean.getSessionUsuarioDto());
            dto.setFecha(UtilCore.Fecha.obtenerFechaActualDate());
            dto.setTerminal(sessionMBean.getSessionTerminal());
        }

        if (accion == applicationMBean.getNuevo()) {
            try {
                dto.setUsuarioCreacionDto(sessionMBean.getSessionUsuarioDto());
                dto.setFechaCreacion(UtilCore.Fecha.obtenerFechaActualDate());
                dto.setTerminalCreacion(sessionMBean.getSessionTerminal());
                UtilCore.General.toUpperCaseDto(dto);
                nuevo(dto);
                mensajeTrx = UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.ok");
                recursosManager.showMessage(mensajeTrx);

                to = "";//retroceder();
            } catch (Exception ex) {
                mensajeTrx = ex.getMessage();
                recursosManager.showError(ex.getMessage());
                logger.error(mensajeTrx);

                to = null;
            }
        } else if (accion == applicationMBean.getEditar()) {
            try {
                UtilCore.General.toUpperCaseDto(dto);
                editar(dto);
                mensajeTrx = UtilCore.Internacionalizacion.getMensajeInternacional("form.general.mensaje.transaccion.ok");
                recursosManager.showMessage(mensajeTrx);
                to = "";//retroceder();
            } catch (Exception ex) {
                mensajeTrx = ex.getMessage();
                recursosManager.showError(ex.getMessage());
                logger.error(mensajeTrx);
                to = null;
            }
        }
        return to;
    }
    
    public void actualizaStock(ProductoDetaDto dto) {
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        ApplicationMBean applicationMBean = (ApplicationMBean) WebServletContextListener.getApplicationContext().getBean("applicationMBean");
        {
            dto.setUsuarioDto(sessionMBean.getSessionUsuarioDto());
            dto.setFecha(UtilCore.Fecha.obtenerFechaActualDate());
            dto.setTerminal(sessionMBean.getSessionTerminal());
        }
        try {
            UtilCore.General.toUpperCaseDto(dto);
            editar(dto);
        } catch (Exception e) {
            logger.error(e.getMessage());
        }
    }

    //    public String autogenerarSku(ProductoDto dto) {
//        if (this.dto.getAutogenerarSku() == true) {
//            String a = String.valueOf(dto.getNivel3Dto().getParametroPadreDto().getParametroPadreDto().getId());
//            String b = String.valueOf(dto.getNivel3Dto().getParametroPadreDto().getId());
//            String c = String.valueOf(dto.getNivel3Dto().getId());
//            String d = String.valueOf(dto.getMedida());
//            String e = String.valueOf(dto.getId());
//            String cod = (a.substring(0, 3) + b.substring(0, 3) + c.substring(0, 3) + d + e);
//            this.dto.setSku(cod);
//        } else {
//            this.dto.setSku("");
//        }
//        return null;
//    }
    /**
     * Metodo que permite obtener la cantidad de unidades de medida de ,
     * Detalles de producto
     *
     * @since 22/01/2014
     * @param dto
     * @return retorna la cantidad , default 0
     * @throws DAOException
     */
    public int obtenerCantidadPorProdYUM(ProductoDetaDto dto) throws DAOException {
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        List<Object> listaParametros = new ArrayList<Object>();
        String hqsql = "select count(e.id) from ProductoDetaDto as e where e.id=e.id";
        hqsql += " and e.productoDto.id = ?";
        listaParametros.add(dto.getProductoDto().getId());
        hqsql += " and e.unidadMedidaDto.id = ?";
        listaParametros.add(dto.getUnidadMedidaDto().getId());
        if (dto.getId() != null) {
            hqsql += " and id <> ?";
            listaParametros.add(dto.getId());
        }
        return Integer.parseInt(springHibernateDao.ejecutarQueryGeneric(hqsql, listaParametros).get(0).toString());
    }

    /**
     * Metodo que permite buscar los detalles de un producto por empresa
     *
     * @since 23/01/2014
     * @param sqr
     * @return retorna el resultado de la consulta (Lista de detalles de
     * productos)
     * @throws DAOException
     */
    public List<ProductoDetaDto> autoCompletarProductosDetaPorEmpresa(final String sqr) throws DAOException {
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        String hqsql = "select e from ProductoDetaDto as e where e.id=e.id";
        hqsql += " and  (upper(e.productoDto.descripcion) like '%" + sqr.toUpperCase() + "%'";
        hqsql += " or upper(e.sku) like '%" + sqr.toUpperCase() + "%'";
        hqsql += " or upper(e.productoDto.descripcionCorta) like '%" + sqr.toUpperCase() + "%'";
        hqsql += " or upper(e.productoDto.descripcionDetalle) like '%" + sqr.toUpperCase() + "%'";
        hqsql += " or upper(e.productoDto.descripcionIdioma1) like '%" + sqr.toUpperCase() + "%'";
        hqsql += " or upper(e.productoDto.descripcionIdioma2) like '%" + sqr.toUpperCase() + "%'";
        hqsql += " or upper(e.unidadMedidaDto.nombre) like '%" + sqr.toUpperCase() + "%'";
        hqsql += ")";
        List<Object> listaParametros = new ArrayList<Object>();
        hqsql += " and e.productoDto.empresaDto.id = ? ";
        listaParametros.add(sessionMBean.getEmpresaDto().getId());
        hqsql += " and e.productoDto.estado = ?";
        listaParametros.add(Boolean.TRUE);
        //Agregamos la condicion que valida propietarios
        if (sessionMBean.getOrganizacionDto() != null && sessionMBean.getOrganizacionDto().getId() != null) {
            hqsql += " and exists(select 'X' from PropietarioDto as prop ";
            hqsql += " where prop.pk.organizacionDto.id = ? ";
            hqsql += " and prop.pk.entidad = ? ";
            hqsql += " and prop.pk.registro = e.productoDto.id  and prop.estado = ?)";
            listaParametros.add(sessionMBean.getOrganizacionDto().getId());
            listaParametros.add(productoManager.getIdEntidad());
            listaParametros.add(Boolean.TRUE);
        }
        hqsql += " order by e.productoDto.descripcion asc";
        return springHibernateDao.ejecutarQuery(hqsql, listaParametros);
    }

    /**
     * Metodo que permite buscar los detalles de un servicio por empresa
     *
     * @since 23/01/2014
     * @param sqr
     * @return retorna el resultado de la consulta (Lista de detalles de
     * servicios)
     * @throws DAOException
     * @see los servicios también estan incluidos en la tabla de productos
     */
    public List<ProductoDetaDto> autoCompletarProductosDetaNoServicioPorEmpresa(final String sqr) throws DAOException {
        SessionMBean sessionMBean = (SessionMBean) WebServletContextListener.getApplicationContext().getBean("sessionMBean");
        String hqsql = "select e from ProductoDetaDto as e where e.id=e.id";
        hqsql += " and  (upper(e.productoDto.descripcion) like '%" + sqr.toUpperCase() + "%'";
        hqsql += " or upper(e.sku) like '%" + sqr.toUpperCase() + "%'";
        hqsql += " or upper(e.productoDto.descripcionCorta) like '%" + sqr.toUpperCase() + "%'";
        hqsql += " or upper(e.productoDto.descripcionDetalle) like '%" + sqr.toUpperCase() + "%'";
        hqsql += " or upper(e.productoDto.descripcionIdioma1) like '%" + sqr.toUpperCase() + "%'";
        hqsql += " or upper(e.productoDto.descripcionIdioma2) like '%" + sqr.toUpperCase() + "%'";
        hqsql += " or upper(e.unidadMedidaDto.nombre) like '%" + sqr.toUpperCase() + "%'";
        hqsql += ")";
        List<Object> listaParametros = new ArrayList<Object>();
        hqsql += " and e.productoDto.empresaDto.id = ? ";
        listaParametros.add(sessionMBean.getEmpresaDto().getId());
        hqsql += " and e.productoDto.tipoProducto <> '" + ConstantesConf.ValoresConstantes.PRODUCTO_COD_TIPO_SERVICIO + "' ";
        hqsql += " and e.productoDto.estado = ?";
        listaParametros.add(Boolean.TRUE);
        //Agregamos la condicion que valida propietarios
        if (sessionMBean.getOrganizacionDto() != null && sessionMBean.getOrganizacionDto().getId() != null) {
            hqsql += " and exists(select 'X' from PropietarioDto as prop ";
            hqsql += " where prop.pk.organizacionDto.id = ? ";
            hqsql += " and prop.pk.entidad = ? ";
            hqsql += " and prop.pk.registro = e.productoDto.id  and prop.estado = ?)";
            listaParametros.add(sessionMBean.getOrganizacionDto().getId());
            listaParametros.add(productoManager.getIdEntidad());
            listaParametros.add(Boolean.TRUE);
        }
        hqsql += " order by e.productoDto.descripcion asc";
        return springHibernateDao.ejecutarQuery(hqsql, listaParametros);
    }

    public static Logger getLogger() {
        return logger;
    }

    public static void setLogger(Logger logger) {
        ProductoDetaManager.logger = logger;
    }

    public Long getIdEntidad() {
        return idEntidad;
    }

    public void setIdEntidad(Long idEntidad) {
        this.idEntidad = idEntidad;
    }

    public DAOGenerico<ProductoDetaDto> getSpringHibernateDao() {
        return springHibernateDao;
    }

    public void setSpringHibernateDao(DAOGenerico<ProductoDetaDto> springHibernateDao) {
        this.springHibernateDao = springHibernateDao;
    }

    public RecursosManager getRecursosManager() {
        return recursosManager;
    }

    public void setRecursosManager(RecursosManager recursosManager) {
        this.recursosManager = recursosManager;
    }
}
